/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <memory>
#include <string>
#include <fstream>

#include <grpcpp/grpcpp.h>

#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "gp.grpc.pb.h"
#endif

#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>

#include "/home/hcgy/Documents/esm6800h/app/common.h"
#include "/home/hcgy/Documents/esm6800h/app/can_uim.h"
#include "/home/hcgy/Documents/esm6800h/app/msg_def.h"
#include "/home/hcgy/Documents/esm6800h/app/config/config.h"
#include "/home/hcgy/Documents/esm6800h/test/data_proc/board_data_proc.h"
#include "action_manage.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using gp::AxisMoveParam;
using gp::Response;
using gp::EmptyRequest;
using gp::OpenLid;
using gp::SCanCode;
using gp::XRModule;
using gp::DP8;
using gp::ThermalSeal;
using gp::DP1;
using gp::Logistics_Purify;
using gp::Door_Ctl;
using gp::DJ_Purify;
using gp::DJ_Qpcr;
using gp::Module;
using gp::ConfigFileTrans;
using gp::enConfigFileId;
using gp::FileTransParam;
using gp::ShakeMagnet;
using gp::ShakeParam;
using gp::SmoothParam;
using gp::TecanTipParam;
using gp::TecanLiquidParam;
using gp::SuckParam;
using gp::TecanInitParam;
using gp::TransTubeParam;
using gp::Dp8LldParam;
using gp::Dp8CapSampleParam;
using gp::TemperatureParam;
using gp::HeatCtlParam;
using gp::ShakeRotateParam;
using gp::MotorMove;
using gp::MotorType;
using gp::ScancodeParam;

using grpc::ServerReader;
using grpc::ServerReaderWriter;
using grpc::ServerWriter;




typedef enum
{
  PARAM_FOR_DP8LLD,
  PARAM_FOR_DP8CAPSAMPLE,
  PARAM_FOR_HEATSEAL_HEAT,
  PARAM_FOR_PURIFY_HEAT,
  PARAM_FOR_SCANCODE,
}en_param_type;

using namespace std;

#if  defined(__x86_64)
#define msgQueueKeyPath "/home/hcgy/Documents/esm6800h/test/msg.tmp" 
#else
#define msgQueueKeyPath "/home/usr/msg/msg.tmp"
#endif

int g_msg_id = -1;

//
int sendMsgToAct(const AxisMoveParam* request,int msgType,unsigned char sidIn,
unsigned char indexOnBoard = 0);

int  sendModuleMsgToAct(int msgType,int moduleIdIn);

int  sendModuleMsgToAct(int msgType,int moduleIdIn, void * paramIn, int paramType);
//the uint of timeOut is second
//int wait_ack(int timeOut,msgQueueAck * ackMsg,Response* reply);

int wait_ack_module(int timeOut,msgQueueAck * ackMsg,Response* reply,int moduleId);

int wait_ack(int timeOut,msgQueueAck * ackMsg,Response* reply,int sid);

int  sendMsgToAdp(const void * paramIn,unsigned int opcode);

int  sendMsgToAct(const void * paramIn,int paramType);

int  sendMsgToShake(const void * paramIn,unsigned int opcode, int paramType);

int  sendModuleMsgToDp1TransAct(int msgType,int moduleIdIn, const TransTubeParam* request);

int  sendMsgToAct_op(const void* requestIn,unsigned char sidIn, int opcode);

int  sendMsgToDjLiquidAct(const gp::DjLiquidParam* request,unsigned int idPump);

// Logic and data behind the server's behavior.
class OpenLidServiceImpl final : public OpenLid::Service {
  Status OpenLid_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {
    //std::string prefix("Hello ");
    //std::cout << "openLid Y: speed:"<<request->speed()<<",position:"<<request->positon()<<endl;
    //std::cout << ",acc:"<<request->acc()<<",dec:"<<request->dec()<<endl;
    
    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,11);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(20,&stMsgQueueAck,reply,11);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status OpenLid_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {
    //std::string prefix("Hello ");
    std::cout << "openLidZ: speed:"<<request->speed()<<",position:"<<request->position()<<endl;
    std::cout << ",acc:"<<request->acc()<<",dec:"<<request->dec()<<endl;
    
    
    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,10);

    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }

    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,10); 

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status OpenLid_Jaw(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {
    //std::string prefix("Hello ");
    std::cout << "openLidJaw: speed:"<<request->speed()<<",position:"<<request->position()<<endl;
    std::cout << ",acc:"<<request->acc()<<",dec:"<<request->dec()<<endl;
    
    
    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,0x01,1);

    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,81); 

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status Init_one(ServerContext* context, const MotorMove* request,
                  Response* reply) override {
    //std::string prefix("Hello ");

    int indexMotor = request->motor();
    std::cout << "openLid Init_one: id:"<<indexMotor<<endl;
    
    int sid = 0;

    switch(indexMotor)
    {
      case MotorType::MT_OPENLID_Z:
      {
        sid = 10;
      }
      break;
      case MotorType::MT_OPENLID_Y:
      {
        sid = 11;
      }
      break;
      case MotorType::MT_OPENLID_JAW:
      {
        sid = 81;
      }
      break;
      default:
      break;
    }

    if(sid==0)
    {
      reply->set_statecode(1);
      reply->set_errornum(PARAM_INVALID);
      return Status::OK;
    }
    
    //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,0x01,1);
    int ret = sendMsgToAct_op(request,sid,UIM_MOTOR_INIT);

    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(30,&stMsgQueueAck,reply,sid); 

    //reply->set_statecode(0);
    return Status::OK;
  }

};

class SCanCodeServiceImpl final : public SCanCode::Service {
  Status SCanCode_rotate(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,12);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,12);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status SCanCode_ctl(ServerContext* context, const ScancodeParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,PARAM_FOR_SCANCODE);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,61);    

    //reply->set_statecode(0);
    return Status::OK;
  }
};

class LogisticsPServiceImpl final : public Logistics_Purify::Service {
  Status Logistics_X(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,40);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,40);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status Logistics_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,38);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,38);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status Logistics_X_Change(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,41);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,41);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status Logistics_Y_Up(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,39);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,39);    

    //reply->set_statecode(0);
    return Status::OK;
  }

};

class Door_CtlServiceImpl final : public Door_Ctl::Service {
  Status Waste_Stuff(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,42);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,42);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DNA_Buff(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,43);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,43);    

    //reply->set_statecode(0);
    return Status::OK;
  } 

};

class XRModuleServiceImpl final : public XRModule::Service {
  Status XRModule_rotate(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,17);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,17);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status XRModule_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,16);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,16);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status XRModule_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,19);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,19);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status XRModule_Jaw(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,18);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,18);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status Init_one(ServerContext* context, const MotorMove* request,
                  Response* reply) override {
    //std::string prefix("Hello ");

    int indexMotor = request->motor();
    std::cout << "openLid Init_one: id:"<<indexMotor<<endl;
    
    int sid = 0;

    switch(indexMotor)
    {
      case MotorType::MT_XR_Y:
      {
        sid = 16;
      }
      break;
      case MotorType::MT_XR_Z:
      {
        sid = 19;
      }
      break;
      default:
      break;
    }

    if(sid==0)
    {
      reply->set_statecode(1);
      reply->set_errornum(PARAM_INVALID);
      return Status::OK;
    }
    
    //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,0x01,1);
    int ret = sendMsgToAct_op(request,sid,UIM_MOTOR_INIT);

    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(30,&stMsgQueueAck,reply,sid); 

    //reply->set_statecode(0);
    return Status::OK;
  }
};

class DP8ServiceImpl final : public DP8::Service {

  Status DP8_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,37);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(90,&stMsgQueueAck,reply,37);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP8_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,15);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(30,&stMsgQueueAck,reply,15);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP8_X(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,36);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(90,&stMsgQueueAck,reply,36);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP8_Suck(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,14);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(60,&stMsgQueueAck,reply,14);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP8_DropTip(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,32);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(60,&stMsgQueueAck,reply,32);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP8_JawZ(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,34);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(60,&stMsgQueueAck,reply,34);    

    //reply->set_statecode(0);
    return Status::OK;
  }

    Status DP8_Jaw(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,35);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(60,&stMsgQueueAck,reply,35);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,33);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(60,&stMsgQueueAck,reply,33);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_Pump(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,47);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(60,&stMsgQueueAck,reply,47);    

    //reply->set_statecode(0);
    return Status::OK;
  }

};


class ThermalSealServiceImpl final : public ThermalSeal::Service {

  Status ThermalSeal_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,13);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,13);    

    //reply->set_statecode(0);
    return Status::OK;
  } 
  
  Status Heat_Control(ServerContext* context, const TemperatureParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,PARAM_FOR_HEATSEAL_HEAT);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,60);    

    //reply->set_statecode(0);
    return Status::OK;
    } 

  Status ThermalSeal_X(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,16);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,16);    

    //reply->set_statecode(0);
    return Status::OK;
  }

};

class DjQpcrServiceImpl final : public DJ_Qpcr::Service {

  Status DJ_X(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,12);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,12);    

    //reply->set_statecode(0);
    return Status::OK;
  } 
  
  Status DJ_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,17);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,17);    

    //reply->set_statecode(0);
    return Status::OK;
  } 

  Status DJ_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,28);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,28);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_Pump(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,46);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,46);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_JawZ(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,18);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,18);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_Jaw(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,19);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,19);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_OutCleanPump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idOutCleanPump = 16;

    int ret = sendMsgToDjLiquidAct(request,idOutCleanPump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idOutCleanPump);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_InCleanPump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idInCleanPump = 16+1;

    int ret = sendMsgToDjLiquidAct(request,idInCleanPump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idInCleanPump);    

    //reply->set_statecode(0);
    return Status::OK;
  }  
  //rpc DJ_WasteLiquidPump (DjLiquidParam) returns (Response) {}
  //rpc DJ_InCleanValve (DjLiquidParam) returns (Response) {}
  Status DJ_InCleanValve(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idInCleanValve = 16+2;

    int ret = sendMsgToDjLiquidAct(request,idInCleanValve);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idInCleanValve);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_WasteLiquidPump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idWastePump = 3;

    int ret = sendMsgToDjLiquidAct(request,idWastePump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idWastePump);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_WasteLiquidValve(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idWasteValve = 16 + 4;

    int ret = sendMsgToDjLiquidAct(request,idWasteValve);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idWasteValve);    

    //reply->set_statecode(0);
    return Status::OK;
  }

};

class DjPurifyServiceImpl final : public DJ_Purify::Service {

  Status DJ_X(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,29);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,29);    

    //reply->set_statecode(0);
    return Status::OK;
  } 
  
  Status DJ_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,30);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,30);    

    //reply->set_statecode(0);
    return Status::OK;
  } 

  Status DJ_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,31);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,31);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_Pump_Big(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,44);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,44);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_Pump_Small(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,45);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,45);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_OutCleanPump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idOutCleanPump = 0;

    int ret = sendMsgToDjLiquidAct(request,idOutCleanPump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idOutCleanPump);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_InCleanPump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idInCleanPump = 1;

    int ret = sendMsgToDjLiquidAct(request,idInCleanPump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idInCleanPump);    

    //reply->set_statecode(0);
    return Status::OK;
  }  
  //rpc DJ_WasteLiquidPump (DjLiquidParam) returns (Response) {}
  //rpc DJ_InCleanValve (DjLiquidParam) returns (Response) {}
  Status DJ_InCleanValve(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idInCleanValve = 2;

    int ret = sendMsgToDjLiquidAct(request,idInCleanValve);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idInCleanValve);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_WasteLiquidPump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idWastePump = 3;

    int ret = sendMsgToDjLiquidAct(request,idWastePump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idWastePump);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_WasteLiquidValve(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idWasteValve = 4;

    int ret = sendMsgToDjLiquidAct(request,idWasteValve);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idWasteValve);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_InCleanValve_small(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idInValve_s = 5;

    int ret = sendMsgToDjLiquidAct(request,idInValve_s);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idInValve_s);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DJ_MagWastepump(ServerContext* context, const gp::DjLiquidParam* request,
                  Response* reply) override {

    const unsigned int idMagWastePump = 16+3;

    int ret = sendMsgToDjLiquidAct(request,idMagWastePump);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(request->duration()/1000 + 5,&stMsgQueueAck,reply,84+idMagWastePump);    

    //reply->set_statecode(0);
    return Status::OK;
  }

};


class DP1ServiceImpl final : public DP1::Service {  

  Status Tube_Jaw(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,1,0);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ACT_MSG_ERROR);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,80);

    // const int WONTEC_JAW_DEVID = 5;

    // if(g_ptrEleCtlManage->getActStatus(100+WONTEC_JAW_DEVID) == ACT_RUNNING)
    // {
    //   printf("dev[%d] is running\n",100+WONTEC_JAW_DEVID);
    //   reply->set_statecode(1);
    //   reply->set_errornum(ACT_ALREADY_RUNNINMG);
    //   return Status::OK;
    // }

    // wontec_queue_msg wtQueueMsg;
    // memset(&wtQueueMsg,0,sizeof(wontec_queue_msg));

    // char funcode = 0;
    // wtQueueMsg.wontecMsg.tarDev = WONTEC_JAW_DEVID;
    // wtQueueMsg.wontecMsg.msgSrc = MSG_FROM_GRPC;
    // if(request->position()==0)
    // {
    //   wtQueueMsg.wontecMsg.funcCode = 8;//'G'
    // }
    // else if(request->position()==1) //close
    // {
    //   wtQueueMsg.wontecMsg.funcCode = 6;//'E'
    //   wtQueueMsg.wontecMsg.paramLen = 1;
    //   wtQueueMsg.wontecMsg.paramData[0] = '1';  
    // }
    // else if(request->position()==2) //open
    // {
    //   wtQueueMsg.wontecMsg.funcCode = 6;//'E'
    //   wtQueueMsg.wontecMsg.paramLen = 1;
    //   wtQueueMsg.wontecMsg.paramData[0] = '2';
    // }

    // wtQueueMsg.type = QUEUE_MSG_TYPE_RS485;

    // if(msgsnd(g_msg_id, (void*)&wtQueueMsg, sizeof(wontec_msg_def), 0) < 0)
    // {
    //     printf("msg send failed\n");
    //     reply->set_statecode(1);
    //     reply->set_errornum(ACT_MSG_ERROR);
    //     return Status::OK;
    // }
    // else
    // {
    //     g_ptrEleCtlManage->setActStatus(100+WONTEC_JAW_DEVID,ACT_RUNNING);
    //     printf("msg send success,type is %d,opcode[%d]\n",wtQueueMsg.type,wtQueueMsg.wontecMsg.funcCode);
    // }
    // msgQueueAck stMsgQueueAck;
    // memset(&stMsgQueueAck,0,sizeof(msgQueueAck));  
    // wait_ack(20,&stMsgQueueAck,reply,100+WONTEC_JAW_DEVID);
    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_Y(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,21);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,21);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_X(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,20);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,20);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_JawZ(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);

      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,22);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_Z(ServerContext* context, const AxisMoveParam* request,
                  Response* reply) override {

    int ret = sendMsgToAdp(request,TECAN_Z_MOVE);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,1);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status DP1_LoadTip(ServerContext* context, const TecanTipParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_LOAD_TIP);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(30,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_DropTip(ServerContext* context, const TecanTipParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_DROP_TIP);
  if(ret)
  {
    reply->set_statecode(1);    
    reply->set_errornum(ret);    
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(30,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_Suck(ServerContext* context, const TecanLiquidParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_SUCK);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(30,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_Spit(ServerContext* context, const TecanLiquidParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_SPIT);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(60,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_SuckExt(ServerContext* context, const SuckParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_SUCK_EXT);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(90,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_SuckPressure(ServerContext* context, const SuckParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_SUCK_P);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(90,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_Init(ServerContext* context, const TecanInitParam* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_INIT);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(30,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }

  Status DP1_Reset(ServerContext* context, const EmptyRequest* request,
                Response* reply) override {

  //int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_UIM,22);
  int ret = sendMsgToAdp(request,TECAN_RESET);
  if(ret)
  {
    reply->set_statecode(1);
    reply->set_errornum(ret);
    return Status::OK;
  }
  
  msgQueueAck stMsgQueueAck;
  memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

  wait_ack(30,&stMsgQueueAck,reply,1);    

  //reply->set_statecode(0);
  return Status::OK;
  }
};

class ModuleServiceImpl final : public Module::Service {

  Status OpenLid(ServerContext* context,const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,0);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    //wait_ack(30,&stMsgQueueAck,reply);
    wait_ack_module(80,&stMsgQueueAck,reply,0);    
    //sleep(60);
    //reply->set_statecode(0);
    printf("OpenLid finished, grpc return\n");
    return Status::OK;
  }

  Status CloseLid(ServerContext* context, const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,1);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    //wait_ack(30,&stMsgQueueAck,reply);  
    //sleep(60);  
    wait_ack_module(70,&stMsgQueueAck,reply,1);

    //reply->set_statecode(0);
    printf("CloseLid finished, grpc return\n");
    return Status::OK;
  }

  Status XR_AToB(ServerContext* context, const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,2);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(120,&stMsgQueueAck,reply,2); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("XR_AToB finished, grpc return\n");
    return Status::OK;
  }

  Status DP8_MOVE(ServerContext* context, const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_FILE_DP8);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(70,&stMsgQueueAck,reply,I_FILE_DP8); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("DP8 MOVE finished, grpc return\n");
    return Status::OK;
  }

  Status DP8_SUCK(ServerContext* context, const Dp8LldParam* request, Response* reply) override {

    dp8_lld dp8LldParam;
    dp8LldParam.threshold = request->threshold();
    dp8LldParam.acc = request->acc();
    dp8LldParam.dec = request->dec();
    dp8LldParam.maxPosition = request->maxposition();
    dp8LldParam.speed = request->speed();
    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP8SUCK,&dp8LldParam,PARAM_FOR_DP8LLD);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(60*1000,&stMsgQueueAck,reply,I_MODULE_DP8SUCK); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("DP8 SUCK finished, grpc return\n");
    return Status::OK;
  }

  Status DP8_SPIT(ServerContext* context, const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP8SPIT);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(60*4,&stMsgQueueAck,reply,I_MODULE_DP8SPIT); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("DP8 spit finished, grpc return\n");
    return Status::OK;
  }

  Status DP8_TipDown(ServerContext* context, const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP8DROPTIP);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(60*4,&stMsgQueueAck,reply,I_MODULE_DP8DROPTIP); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("DP8 drop tip finished, grpc return\n");
    return Status::OK;
  }

  Status DP8_TipOn(ServerContext* context, const EmptyRequest* request, Response* reply) override {

    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP8ONTIP);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(60*4,&stMsgQueueAck,reply,I_MODULE_DP8ONTIP); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("DP8 put tip on finished, grpc return\n");
    return Status::OK;
  }

  Status Heat_Seal(ServerContext* contexts, const EmptyRequest* request, Response* reply) override {

    printf("server enter in Heat_Seal\n");
    int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_FILE_THREMAL_SEAL);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(60*4,&stMsgQueueAck,reply,I_FILE_THREMAL_SEAL); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("Heat_Seal finished, grpc return\n");
    return Status::OK;
  }

  Status DP1_TransTube(ServerContext* contexts, const TransTubeParam* request, Response* reply) override {

    printf("server enter in DP1_TransLid\n");
    int ret = sendModuleMsgToDp1TransAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP1TRANSTUBE,request);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
    wait_ack_module(60*4,&stMsgQueueAck,reply,I_MODULE_DP1TRANSTUBE); 
    //wait_ack(20,&stMsgQueueAck,reply);
    //sleep(60);    

    //reply->set_statecode(0);
    printf("DP1_TransLid finished, grpc return\n");
    return Status::OK;
  }

Status DP8_LLD(ServerContext* contexts, const Dp8LldParam* request, Response* reply) override {
      printf("server enter in DP8_LLD\n");

      dp8_lld dp8LldParam;
      dp8LldParam.threshold = request->threshold();
      dp8LldParam.maxPosition = request->maxposition();
      dp8LldParam.acc = request->acc();
      dp8LldParam.dec = request->dec();
      dp8LldParam.speed = request->speed();

      int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP8LLD,&dp8LldParam,PARAM_FOR_DP8LLD);

      if(ret)
      {
        reply->set_statecode(1);
        reply->set_errornum(ret);
        return Status::OK;
      }
      
      msgQueueAck stMsgQueueAck;
      memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
      wait_ack_module(60,&stMsgQueueAck,reply,I_MODULE_DP8LLD); 

      
      printf("DP8_LLD finished, grpc return\n");
      return Status::OK;      
}

Status DP8_CapSample(ServerContext* contexts, const Dp8CapSampleParam* request, Response* reply) override {
      printf("server enter in DP8_CapSample\n");

      dp8capSample dpSampleParam;
      dpSampleParam.interval = request->interval();
      dpSampleParam.position = request->position();
      dpSampleParam.acc = request->acc();
      dpSampleParam.dec = request->dec();
      dpSampleParam.speed = request->speed();
      dpSampleParam.chanMask = request->chanmask();

      int ret = sendModuleMsgToAct(QUEUE_MSG_TYPE_MODULE,I_MODULE_DP8SAMPLE,&dpSampleParam,PARAM_FOR_DP8CAPSAMPLE);

      if(ret)
      {
        reply->set_statecode(1);
        reply->set_errornum(ret);
        return Status::OK;
      }
      
      msgQueueAck stMsgQueueAck;
      memset(&stMsgQueueAck,0,sizeof(msgQueueAck));
      wait_ack_module(65*2,&stMsgQueueAck,reply,I_MODULE_DP8SAMPLE); 

      
      printf("DP8_CapSample finished, grpc return\n");
      return Status::OK;      
}

  
};
//#define MAX_FILE_INDEX  6
#define CONFIG_FILE_PREFIX "/mnt/nandflash/apps/config/"
#define _DEBUG_MY 1
#if _DEBUG_MY
const char * fileNames[enConfigFileId::MAX_FILE_INDEX] = 
{
    "openlid.json",
    "closelid.json",
    "xr.json",
    "bash.json",
    "trans.json",
    "dp8.json",
    "heat_seal.json",
    "dj.json",
    "bath.json",
    "dp8suck.json",
    "dp8tip.json",
    "dp8spit.json",
    "dp8tip.json",
    "xr.json",
    "xr.json",
    "bath.json",
    "djaddsample.xml",
    "djclean.json",    
    "dp8suck_ab.json",
};
#else
const char * fileNames[enConfigFileId::MAX_FILE_INDEX] = 
{
    "/mnt/nandflash/apps/config/openlid.json",
    "/mnt/nandflash/apps/config/closelid.json",
    "/mnt/nandflash/apps/config/xr.json",
    "/mnt/nandflash/apps/config/bath.json",
    "/mnt/nandflash/apps/config/trans.json",
    "/mnt/nandflash/apps/config/dp8.json",
    "/mnt/nandflash/apps/config/heat_seal.json",
};
#endif

#define CHUNK_SIZE 1024

class ConfigFileTransServiceImpl final : public ConfigFileTrans::Service {

  Status transToPc(ServerContext* context,const FileTransParam * fileParamIn,ServerWriter<FileTransParam>* writer) override {

    enConfigFileId fileId = fileParamIn->fileid();
    std::ifstream infile;

    FileTransParam transChunk;
    
    char data[CHUNK_SIZE];

    int len = 0;
    char srcFileName[256] = {0};
    sprintf(srcFileName,"%s%s",CONFIG_FILE_PREFIX,fileNames[fileId]);
    infile.open(srcFileName, std::ifstream::in | std::ifstream::binary);

    if(!infile.is_open())
    {
       std::cout<<"Error open file, fileId:"<<fileId<<"fileName:"<<srcFileName<<std::endl;
       return Status::OK; 
    }

    infile.seekg(0, infile.end);
	  size_t fileSize = infile.tellg();
    infile.seekg(0, infile.beg);
    

    std::cout<<"file id:"<<fileParamIn->fileid()<<", file size:"
    <<fileSize<<", file name:"<<srcFileName<<std::endl;

    //std::unique_ptr<ServerWriter<FileTransParam>> writer(stub_->transToPc(&context, fileParamIn));
    
    while (!infile.eof()) {
      infile.read(data, CHUNK_SIZE);
      transChunk.set_chunk(data, infile.gcount());
      transChunk.set_filesize(fileSize);
      if (!writer->Write(transChunk)) {
        // Broken stream.
        break;
      }
      len += infile.gcount();
    }

    infile.close();
    //writer->WritesDone();
    //writer->Finish();
    //sleep(60);
    //reply->set_statecode(0);
    printf("transToPc finished, grpc return\n");
    return Status::OK;
  } 

  Status transToCtlBorad(ServerContext* context,ServerReader<FileTransParam>* reader,Response *reply) override {
      FileTransParam transChunk;
      
      std::ofstream outfile;
      const char *data;
      int fileSize = 0;

      int fileId = 0;
      std::cout<<"start receive file from PC on server"<<std::endl;

      char dstFileName[256] = {0};
      
      if(reader->Read(&transChunk))
      {
        const char *filename = "./serverRecvTmp.txt";//fileNames[transChunk.fileid()];

        fileId = transChunk.fileid();
        fileSize = transChunk.filesize();
        outfile.open(filename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
        data = transChunk.chunk().c_str();
        outfile.write(data, transChunk.chunk().length());
        while (reader->Read(&transChunk)) {
            data = transChunk.chunk().c_str();
            outfile.write(data, transChunk.chunk().length());
        }
        long pos = outfile.tellp();

        

        if(pos == fileSize)
        {

          outfile.flush();
          outfile.close();
          std::cout<<"server recv file success, "<<"filesize:"<<fileSize<<std::endl;
          sprintf(dstFileName,"%s%s",CONFIG_FILE_PREFIX,fileNames[transChunk.fileid()]);
          //errno = 0;
          //int moveRet = rename(filename,dstFileName);

          //if(moveRet)
          //{
            //printf("rename file failed\n",errno);
            //perror("rename file failed");
            char cmdMove[256] = {0};
            int accRet = access(dstFileName, 0);
            sprintf(cmdMove,"rm %s",dstFileName);

            int cntTimeOut = 0;
            
            while(accRet==0)
            {//file exist
               system(cmdMove); 
               usleep(10000);
               cntTimeOut ++ ;
               if(cntTimeOut > 10)
               {
                 break;
               }
               accRet = access(dstFileName, 0); 
            }           
            
            sprintf(cmdMove,"mv %s %s",filename,dstFileName);
            system(cmdMove);

            usleep(10000);
            cntTimeOut = 0;
            accRet = access(dstFileName, 0);
            while(accRet==-1)
            {//file not exist
               system(cmdMove); 
               usleep(10000);
               cntTimeOut ++ ;
               if(cntTimeOut > 10)
               {
                 break;
               }
               accRet = access(dstFileName, 0); 
            }            
          //}
          std::cout<<"write to "<<dstFileName<<std::endl;
          reply->set_statecode(100);
          reply->set_errornum(100);
        }
        else
        {
          std::cout<<"pos:"<<pos<<",fileSize:"<<fileSize<<std::endl;
          outfile.flush();
          outfile.close();
          reply->set_statecode(2);
          reply->set_errornum(2);
        }
        //reply->set_statecode(0);
        
      }

      std::cout<<"server recv file end"<<std::endl<<"filesize:"<<fileSize<<std::endl;
      return Status::OK;     
      
  } 

  
};


class ShakeMagnetServiceImpl final : public ShakeMagnet::Service {  

  Status Start_Shake(ServerContext* context, const ShakeParam* request,
                  Response* reply) override {

    // int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,1,2);
    int ret = sendMsgToShake(request,CENTRE_START,PURIFY_SHAKE);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ACT_MSG_ERROR);
      return Status::OK;
    }
    
    // msgQueueAck stMsgQueueAck;
    // memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    // wait_ack(20,&stMsgQueueAck,reply,84);    

    reply->set_statecode(100);
    reply->set_errornum(100);

    return Status::OK;
  }

  Status Stop_Shake(ServerContext* context, const ShakeParam* request,
                  Response* reply) override {

    // int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,1,2);
    int ret = sendMsgToShake(request,CENTRE_STOP,PURIFY_SHAKE);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ACT_MSG_ERROR);
      return Status::OK;
    }
    
    // msgQueueAck stMsgQueueAck;
    // memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    // wait_ack(20,&stMsgQueueAck,reply,84);    

    reply->set_statecode(100);
    reply->set_errornum(100);

    return Status::OK;
  }
  
  Status Set_Shake_DutyCycle(ServerContext* context, const ShakeParam* request,
                  Response* reply) override {

    // int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,1,2);
    int ret = sendMsgToShake(request,CENTRE_CONFIG,PURIFY_DUTYCYCLE);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ACT_MSG_ERROR);
      return Status::OK;
    }
    
    // msgQueueAck stMsgQueueAck;
    // memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    // wait_ack(20,&stMsgQueueAck,reply,84);    

    reply->set_statecode(100);
    reply->set_errornum(100);

    return Status::OK;
  }

  Status Set_Shake_rotateSpeed(ServerContext* context, const ShakeRotateParam* request,
                  Response* reply) override {

    // int ret = sendMsgToAct(request,QUEUE_MSG_TYPE_BOARDS,1,2);
    int ret = sendMsgToShake(request,CENTRE_CONFIG,PURIFY_ROTATE_SPEED_CNT);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ACT_MSG_ERROR);
      return Status::OK;
    }
    
    // msgQueueAck stMsgQueueAck;
    // memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    // wait_ack(20,&stMsgQueueAck,reply,84);    

    reply->set_statecode(100);
    reply->set_errornum(100);

    return Status::OK;
  }

  Status Smooth(ServerContext* context, const SmoothParam* request,
                  Response* reply) override {

    AxisMoveParam moveParam = request->move_param(); 
    int eleNum = request->elenum();

    if(eleNum>=5)
    {
      reply->set_statecode(1);
      reply->set_errornum(1);
      return Status::OK;
    }

    int sidArr[5] = {27,26,25,24,23};
    
    int sid = sidArr[eleNum];

    int ret = sendMsgToAct(&moveParam,QUEUE_MSG_TYPE_UIM,sid);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,sid);    

    //reply->set_statecode(0);
    return Status::OK;
  }

  Status Heat_Control(ServerContext* context, const HeatCtlParam* request,
                  Response* reply) override {


    int ret = sendMsgToAct(request,PARAM_FOR_PURIFY_HEAT);
    if(ret)
    {
      reply->set_statecode(1);
      reply->set_errornum(ret);
      return Status::OK;
    }
    
    msgQueueAck stMsgQueueAck;
    memset(&stMsgQueueAck,0,sizeof(msgQueueAck));

    wait_ack(10,&stMsgQueueAck,reply,61+request->chan());    

    //reply->set_statecode(0);
    return Status::OK;
  }
  
};

void RunServer() {
  std::string server_address("0.0.0.0:50051");
  OpenLidServiceImpl serviceOpenLid;

  SCanCodeServiceImpl serviceScanCode;
  //XRModuleServiceImpl serviceXRModule;

  DP8ServiceImpl serviceDp8;
  ThermalSealServiceImpl serviceThermalSeal;

  DP1ServiceImpl serviceDp1;

  ModuleServiceImpl serviceModule;

  ConfigFileTransServiceImpl serviceConfigFileTrans;
  ShakeMagnetServiceImpl serviceShakeMagnet;

  LogisticsPServiceImpl serviceLogistic;
  Door_CtlServiceImpl serviceDoorMotor;
  DjQpcrServiceImpl serviceDjQ;
  DjPurifyServiceImpl serviceDjP;
  

  ServerBuilder builder;
  // Listen on the given address without any authentication mechanism.
  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  // Register "service" as the instance through which we'll communicate with
  // clients. In this case it corresponds to an *synchronous* service.
  builder.RegisterService(&serviceOpenLid);
  builder.RegisterService(&serviceScanCode);
  //builder.RegisterService(&serviceXRModule);
  builder.RegisterService(&serviceDp8);
  builder.RegisterService(&serviceThermalSeal);
  builder.RegisterService(&serviceModule);

  builder.RegisterService(&serviceConfigFileTrans);

  builder.RegisterService(&serviceDp1);
  builder.RegisterService(&serviceShakeMagnet);
  builder.RegisterService(&serviceLogistic);
  builder.RegisterService(&serviceDoorMotor);
  builder.RegisterService(&serviceDjP);
  builder.RegisterService(&serviceDjQ);
  // Finally assemble the server.
  std::unique_ptr<Server> server(builder.BuildAndStart());
  std::cout << "Server listening on " << server_address << std::endl;

  // Wait for the server to shutdown. Note that some other thread must be
  // responsible for shutting down the server for this call to ever return.
  server->Wait();
}


int main(int argc, char** argv) {

  key_t key = ftok(msgQueueKeyPath, 0x1234);
  if(key < 0)
  {
      perror("ftok");
      return -1;
  }

  int msg_id = msgget(key, IPC_CREAT|0600);//IPC_CREAT|0600
  if(msg_id < 0)
  {
      perror("msgget");
      return -1;
  }
  g_msg_id = msg_id;
  CActionMange eleCtlManage;
  CActionMange moduleManage;
  
  g_ptrEleCtlManage = &eleCtlManage;
  g_ptrModuleManage = &moduleManage;
  appAckRecvexitFlag = 0;
  pthread_t appAckRecvHandl = 0;
  pthread_create(&appAckRecvHandl,NULL,funcRecvAck,&msg_id);

  RunServer();


  appAckRecvexitFlag = 1;
  void * threadRet = NULL;
  pthread_join(appAckRecvHandl,&threadRet);

  if(threadRet)
  {
    free(threadRet);
  }

  return 0;
}


int  sendMsgToAct(const AxisMoveParam* request,int msgType,
     unsigned char sidIn,unsigned char indexOnBoard)
{
    msg_ctl_uim msgFrame;
    int ret = 0;

    int actId = sidIn;
    if(msgType == QUEUE_MSG_TYPE_BOARDS)
    {
        actId = 80 + indexOnBoard;
    }

    if(g_ptrEleCtlManage->getActStatus(actId) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }
    memset(&msgFrame,0,sizeof(msg_ctl_uim));
    msgFrame.ctlFrame.un_cmd.moveCtl.speed = request->speed();
    msgFrame.ctlFrame.sid = sidIn;
    msgFrame.ctlFrame.opcode = MOVE;
    msgFrame.ctlFrame.un_cmd.moveCtl.inc_speed = request->acc();
    msgFrame.ctlFrame.un_cmd.moveCtl.dec_speed = request->dec();
    msgFrame.ctlFrame.un_cmd.moveCtl.position = request->position();
    msgFrame.ctlFrame.un_cmd.moveCtl.ele_index = indexOnBoard;

    msgFrame.type = msgType;
    msgFrame.ctlFrame.msgSrc = MSG_FROM_GRPC;

    g_ptrEleCtlManage->setActStatus(actId,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrEleCtlManage->setActStatus(actId,ACT_FINISHED);
        ret = ACT_MSG_ERROR;
    }
    else
    {        
        
        printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
        ret = 0;
    }
    return ret;
}

int  sendMsgToAct_op(const void* requestIn,unsigned char sidIn, int opcode)
{
    msg_ctl_uim msgFrame;
    int ret = 0;

    int actId = sidIn;

    int msgType = QUEUE_MSG_TYPE_UIM;
    if(sidIn<=83 && sidIn >= 80)
    {
       msgType == QUEUE_MSG_TYPE_BOARDS;
    }

    if(g_ptrEleCtlManage->getActStatus(actId) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }
    
    MotorMove *request = (MotorMove *)requestIn;

    memset(&msgFrame,0,sizeof(msg_ctl_uim));
    msgFrame.ctlFrame.un_cmd.moveCtl.position = request->pos();
    msgFrame.ctlFrame.sid = sidIn;
    msgFrame.ctlFrame.opcode = opcode;
    

    msgFrame.type = msgType;
    msgFrame.ctlFrame.msgSrc = MSG_FROM_GRPC;

    g_ptrEleCtlManage->setActStatus(actId,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrEleCtlManage->setActStatus(actId,ACT_FINISHED);
        ret = ACT_MSG_ERROR;
    }
    else
    {        
        
        printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
        ret = 0;
    }
    return ret;
}

int  sendMsgToAdp(const void * paramIn,unsigned int opcode)
{
    msg_ctl_uim msgFrame;
    int ret = 0;
    memset(&msgFrame,0,sizeof(msg_ctl_uim));
    msgFrame.ctlFrame.opcode = opcode;
    msgFrame.ctlFrame.sid = 1;
    int isValid = 0;
    if(g_ptrEleCtlManage->getActStatus(1) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }

    switch (opcode)
    {
      case TECAN_LOAD_TIP:
      case TECAN_DROP_TIP:
      {
        TecanTipParam * ptrTipParam = (TecanTipParam *)paramIn;

        tecan_tip_param * ptrParam = &(msgFrame.ctlFrame.un_cmd.tecanCtlData.tipParam);
        ptrParam->posRet = ptrTipParam->posret();
        ptrParam->posTip = ptrTipParam->postip();
        ptrParam->speed = ptrTipParam->speed();
        isValid = 1;
      }
      break;
      case TECAN_SUCK:
      case TECAN_SPIT:
      {
        TecanLiquidParam * ptrLiquidParam = (TecanLiquidParam *)paramIn;

        tecan_liquid_param * ptrParam = &(msgFrame.ctlFrame.un_cmd.tecanCtlData.liquidParam);
        ptrParam->posPre = ptrLiquidParam->pospre();
        ptrParam->posPost = ptrLiquidParam->pospost();
        ptrParam->quantity = ptrLiquidParam->quantity();
        ptrParam->posMax = ptrLiquidParam->posmax();//here should be changed together with swagger;
        ptrParam->speed = ptrLiquidParam->speed();
        ptrParam->quanSpitAir1 = ptrLiquidParam->quanspitair1();
        ptrParam->quanSuckBack = ptrLiquidParam->quansuckback();
        ptrParam->delayAfterSpit = ptrLiquidParam->delayafterspit();
        ptrParam->speedGoUp = ptrLiquidParam->speedgoup();
        ptrParam->speedSuckBack = ptrLiquidParam->speedsuckback();
        isValid = 1;
      }
      break;

      case TECAN_Z_MOVE:
      {
        AxisMoveParam * ptrMoveParam = (AxisMoveParam *)paramIn;
        msgFrame.ctlFrame.un_cmd.moveCtl.speed = ptrMoveParam->speed();
        msgFrame.ctlFrame.un_cmd.moveCtl.inc_speed = ptrMoveParam->acc();
        msgFrame.ctlFrame.un_cmd.moveCtl.dec_speed = ptrMoveParam->dec();
        msgFrame.ctlFrame.un_cmd.moveCtl.position = ptrMoveParam->position();
        isValid = 1;
      }
      break;
      case TECAN_SUCK_EXT:
      case TECAN_SUCK_P:
      {
        SuckParam * ptrSuckParam = (SuckParam *)paramIn;
        msgFrame.ctlFrame.un_cmd.suckParam.air1Quan = ptrSuckParam->air1quan();
        msgFrame.ctlFrame.un_cmd.suckParam.air2Quan = ptrSuckParam->air2quan();
        msgFrame.ctlFrame.un_cmd.suckParam.posMax = ptrSuckParam->posmax();
        msgFrame.ctlFrame.un_cmd.suckParam.posPost = ptrSuckParam->pospost();
        msgFrame.ctlFrame.un_cmd.suckParam.posPre = ptrSuckParam->pospre();
        msgFrame.ctlFrame.un_cmd.suckParam.quantity = ptrSuckParam->quantity();
        msgFrame.ctlFrame.un_cmd.suckParam.speedDetect = ptrSuckParam->speeddetect();
        msgFrame.ctlFrame.un_cmd.suckParam.speedPost = ptrSuckParam->speedpost();
        msgFrame.ctlFrame.un_cmd.suckParam.speedPre = ptrSuckParam->speedpre();
        msgFrame.ctlFrame.un_cmd.suckParam.speedSuck = ptrSuckParam->speedsuck();
        msgFrame.ctlFrame.un_cmd.suckParam.stepBelow = ptrSuckParam->stepbelow();
        msgFrame.ctlFrame.un_cmd.suckParam.threshold = ptrSuckParam->threshold();
        // msgFrame.ctlFrame.un_cmd.moveCtl.inc_speed = ptrMoveParam->acc();
        // msgFrame.ctlFrame.un_cmd.moveCtl.dec_speed = ptrMoveParam->dec();
        // msgFrame.ctlFrame.un_cmd.moveCtl.position = ptrMoveParam->position();
        msgFrame.ctlFrame.un_cmd.suckParam.more = ptrSuckParam->more();
        msgFrame.ctlFrame.un_cmd.suckParam.spitQuan = ptrSuckParam->spitquan();

        msgFrame.ctlFrame.un_cmd.suckParam.delayAfterSpit = ptrSuckParam->delayafterspit();
        msgFrame.ctlFrame.un_cmd.suckParam.delayAfterSuck = ptrSuckParam->delayaftersuck();
        msgFrame.ctlFrame.un_cmd.suckParam.speedSuckAir2 = ptrSuckParam->speedsuckair2();
        msgFrame.ctlFrame.un_cmd.suckParam.speedSuckAir1 = ptrSuckParam->speedsuckair1();
        msgFrame.ctlFrame.un_cmd.suckParam.spitSpeed = ptrSuckParam->spitspeed();
        isValid = 1;
      }
      break;
      case TECAN_INIT:
      {
        TecanInitParam * ptrInitParam = (TecanInitParam *)paramIn;
        msgFrame.ctlFrame.un_cmd.tecanCtlData.initParam.detectType = ptrInitParam->liquiddetecttype();
        isValid = 1;
      }
      break;
      case TECAN_RESET:
      {
        isValid = 1;
      }
      break;
      default:
      break;
    }

    if(!isValid)
    {
      printf("param is NOT valid in sendMsgToAdp\n");
      ret = PARAM_INVALID;
      return ret;
    }

    msgFrame.type = QUEUE_MSG_TYPE_UIM;
    g_ptrEleCtlManage->setActStatus(1,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrEleCtlManage->setActStatus(1,ACT_FINISHED);
        ret = ACT_MSG_ERROR;
    }
    else
    {
        
        printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
        ret = 0;
    }
    return ret;
}

int  sendMsgToShake(const void * paramIn,unsigned int opcode, int paramType)
{
    msg_ctl_uim msgFrame;
    int ret = 0;
    memset(&msgFrame,0,sizeof(msg_ctl_uim));
    msgFrame.ctlFrame.opcode = opcode;
    msgFrame.ctlFrame.sid = 4;
    int isValid = 0;

    purifyCtl * ptrPurifyParam = &(msgFrame.ctlFrame.un_cmd.purifyCtlData);
    
    if(paramType==PURIFY_ROTATE_SPEED_CNT)
    {
      ShakeRotateParam * rotateParam = (ShakeRotateParam *)paramIn;

      ptrPurifyParam->chanNum = rotateParam->elenum();
      ptrPurifyParam->rotateSpeedCnt = rotateParam->rotatespeed();
    }
    else
    {
      ShakeParam * shakeParam = (ShakeParam *)paramIn;

    
      ptrPurifyParam->chanNum = shakeParam->elenum();
      ptrPurifyParam->dutyCycle = shakeParam->dutycycle();
      ptrPurifyParam->duration = shakeParam->duration();
    }   

    
    ptrPurifyParam->paramType = paramType;
    

    msgFrame.type = QUEUE_MSG_TYPE_BOARDS;

    if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
    {
        printf("msg send failed\n");
        ret = 1;
    }
    else
    {
        /* code */
        printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
        ret = 0;
    }
    return ret;
}

int  sendMsgToAct(const void * paramIn,int paramType)
{
  msg_ctl_uim msgFrame;
  int ret = 0;
    
  switch (paramType)
  {
    case PARAM_FOR_HEATSEAL_HEAT:
    {
      TemperatureParam * ptrTemprature = (TemperatureParam *)paramIn;
      heatParam * pstHeatParam = &(msgFrame.ctlFrame.un_cmd.heatCtlData);
      pstHeatParam->opcode = ptrTemprature->startorstop()?CENTRE_START:CENTRE_STOP;
      pstHeatParam->heatPlace = HEAT_FOR_HEAT_SEAL;
      pstHeatParam->chan = 0;
      pstHeatParam->temperature = 0;

      msgFrame.type = QUEUE_MSG_TYPE_BOARDS;
      msgFrame.ctlFrame.sid = 5; 
      msgFrame.ctlFrame.opcode = HEAT_CTL;     

    }
    break;
    case PARAM_FOR_PURIFY_HEAT:
    {
      HeatCtlParam * ptrHeatParam = (HeatCtlParam *)paramIn;
      heatParam * pstHeatParam = &(msgFrame.ctlFrame.un_cmd.heatCtlData);
      pstHeatParam->opcode = ptrHeatParam->startorstop()?CENTRE_START:CENTRE_STOP;
      pstHeatParam->heatPlace = HEAT_FOR_SHAKE;
      pstHeatParam->chan = ptrHeatParam->chan();
      pstHeatParam->temperature = ptrHeatParam->temperature();

      msgFrame.type = QUEUE_MSG_TYPE_BOARDS;
      msgFrame.ctlFrame.sid = 4; 
      msgFrame.ctlFrame.opcode = HEAT_CTL; 
    }
    break; 
    case PARAM_FOR_SCANCODE:
    {
      ScancodeParam *pstScancodeParamGrpc = (ScancodeParam *)paramIn;

      scancode_param * pstScancodeParam = &(msgFrame.ctlFrame.un_cmd.scancodeParam);

      pstScancodeParam->chanNum = pstScancodeParamGrpc->scanid();
      pstScancodeParam->isStart = pstScancodeParamGrpc->isstart();
      msgFrame.type = QUEUE_MSG_TYPE_BOARDS;
      msgFrame.ctlFrame.sid = SCANCODE_BOARD; 
      msgFrame.ctlFrame.opcode = SCANCODE_CTL; 
    }
    break;
    default:
    break;
  }
  
  if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
  {
      printf("msg send failed\n");
      ret = 1;
  }
  else
  {
      /* code */
      printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
      ret = 0;
  }
  return ret;

}

int  sendModuleMsgToAct(int msgType,int moduleIdIn)
{
    module_queue_msg ctlFrame;
    int ret =0;

    if(g_ptrModuleManage->getActStatus(moduleIdIn) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }

    ctlFrame.type = msgType;
    ctlFrame.moduleMsg.moduleId = moduleIdIn;
    
    g_ptrModuleManage->setActStatus(moduleIdIn,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&ctlFrame, sizeof(module_msg), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrModuleManage->setActStatus(moduleIdIn,ACT_FINISHED);
        ret = 1;
    }
    else
    {
        
        printf("msg send success,type is %d,msgId[%d]\n",ctlFrame.type,ctlFrame.moduleMsg.moduleId);
        ret = 0;
    }
    return ret;
}

int  sendModuleMsgToAct(int msgType,int moduleIdIn, void * paramIn, int paramType)
{
    module_queue_msg ctlFrame;
    int ret =0;   

    if(g_ptrModuleManage->getActStatus(moduleIdIn) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }


    switch(paramType)
    {
      case PARAM_FOR_DP8LLD:
      {
          dp8_lld * ptrDp8lldParam = (dp8_lld *)paramIn;
          memcpy(&ctlFrame.moduleMsg.un_param.dp8lldParam,ptrDp8lldParam,sizeof(dp8_lld));
      }
      break;

      case PARAM_FOR_DP8CAPSAMPLE:
      {
          dp8capSample * ptrDp8capParam= (dp8capSample *)paramIn;
          memcpy(&ctlFrame.moduleMsg.un_param.dp8capSampleParam,ptrDp8capParam,sizeof(dp8capSample));
      }
      break;
      default:
      break;
    }

    ctlFrame.type = msgType;
    ctlFrame.moduleMsg.moduleId = moduleIdIn;
    
    g_ptrModuleManage->setActStatus(moduleIdIn,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&ctlFrame, sizeof(module_msg), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrModuleManage->setActStatus(moduleIdIn,ACT_FINISHED);
        ret = 1;
    }
    else
    {
        
        printf("msg send success,type is %d,msgId[%d]\n",ctlFrame.type,ctlFrame.moduleMsg.moduleId);
        ret = 0;
    }
    return ret;
}

int  sendModuleMsgToDp1TransAct(int msgType,int moduleIdIn, const TransTubeParam* request)
{
    module_queue_msg ctlFrame;
    int ret =0;

    if(g_ptrModuleManage->getActStatus(moduleIdIn) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }

    ctlFrame.type = msgType;
    ctlFrame.moduleMsg.moduleId = moduleIdIn;
    ctlFrame.moduleMsg.un_param.tubeTransParam.Xsrc = request->srcx();
    ctlFrame.moduleMsg.un_param.tubeTransParam.Ysrc = request->srcy();
    ctlFrame.moduleMsg.un_param.tubeTransParam.Zsrc = request->srcz();
    ctlFrame.moduleMsg.un_param.tubeTransParam.Xtar = request->tarx();
    ctlFrame.moduleMsg.un_param.tubeTransParam.Ytar = request->tary();
    ctlFrame.moduleMsg.un_param.tubeTransParam.Ztar = request->tarz();

    g_ptrModuleManage->setActStatus(moduleIdIn,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&ctlFrame, sizeof(module_msg), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrModuleManage->setActStatus(moduleIdIn,ACT_FINISHED);
        ret = 1;
    }
    else
    {
        
        printf("msg send success,type is %d,msgId[%d]\n",ctlFrame.type,ctlFrame.moduleMsg.moduleId);
        ret = 0;
    }
    return ret;
}

int wait_ack_module(int timeOut,msgQueueAck * ackMsg,Response* reply,int moduleId)
{
  int tmpTimeOut = timeOut;
  int ret = 0;
  if(tmpTimeOut==0)
  {
    tmpTimeOut = 1000;
  }
  else
  {
    tmpTimeOut*=1000;
  }

  int counter = tmpTimeOut/20;

  int statusCodeRecv = 0;
  int errNumRecv = 0;

  while(counter>0)
  {
    if(g_ptrModuleManage->getActStatus(moduleId,&statusCodeRecv,&errNumRecv) != ACT_RUNNING)
    {
      break;
    }
    usleep(20000);

    counter--;
  }

  if(counter<=0)
  {
    reply->set_statecode(2);
    reply->set_errornum(ACT_TIMEOUT_GRPC);
    ret = 1;

    g_ptrModuleManage->setActStatus(moduleId,ACT_TIMEDOUT_GRPC);
  }
  else
  {  
    if(statusCodeRecv)
    {
      reply->set_errornum(errNumRecv);
      reply->set_statecode(2);
      ret = 1;
    }
    else
    {
      reply->set_errornum(100);
      reply->set_statecode(100);
      ret = 0;
    }
    
  }

}

int wait_ack(int timeOut,msgQueueAck * ackMsg,Response* reply,int sid)
{
  int tmpTimeOut = timeOut;
  int ret = 0;
  if(tmpTimeOut==0)
  {
    tmpTimeOut = 1000;
  }
  else
  {
    tmpTimeOut*=1000;
  }

  int counter = tmpTimeOut/20;
  
  int statusCodeRecv = 0;
  int errNumRecv = 0;
  while(counter>0)
  {
    if(g_ptrEleCtlManage->getActStatus(sid,&statusCodeRecv,&errNumRecv) != ACT_RUNNING)
    {
        break;
    }
    usleep(10000);

    counter--;
  }

  if(counter<=0)
  {
    reply->set_statecode(2);
    reply->set_errornum(ACT_TIMEOUT_GRPC);
    ret = 1;
    g_ptrEleCtlManage->setActStatus(sid,ACT_TIMEDOUT_GRPC);
  }
  else
  {  
    if(statusCodeRecv)
    {
      reply->set_errornum(errNumRecv);
      reply->set_statecode(2);
      ret = 1;
    }
    else
    {
      reply->set_errornum(100);
      reply->set_statecode(100);
      ret = 0;
    }
    
  }

}

int  sendMsgToDjLiquidAct(const gp::DjLiquidParam* request,unsigned int idPump)
{
    msg_ctl_uim msgFrame;
    int ret = 0;

    int actId = 84+idPump;

    if(g_ptrEleCtlManage->getActStatus(actId) == ACT_RUNNING)
    {
      ret = ACT_ALREADY_RUNNINMG;
      return ret;
    }

    memset(&msgFrame,0,sizeof(msg_ctl_uim));
    
    msgFrame.ctlFrame.sid = SYSTEM_CTRL_BOARD;
    msgFrame.ctlFrame.opcode = request->startorstop()?CENTRE_START:CENTRE_STOP;
    msgFrame.ctlFrame.un_cmd.djLiquidParam.chanNum = idPump;
    msgFrame.ctlFrame.un_cmd.djLiquidParam.paramType = SYSCTL_LIQUID;
    msgFrame.ctlFrame.un_cmd.djLiquidParam.duration = request->duration();

    msgFrame.type = QUEUE_MSG_TYPE_BOARDS;

    g_ptrEleCtlManage->setActStatus(actId,ACT_RUNNING);
    if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
    {
        printf("msg send failed\n");
        g_ptrEleCtlManage->setActStatus(actId,ACT_FINISHED);
        ret = 1;
    }
    else
    {        
        printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
        ret = 0;
    }
    return ret;
}


// int wait_ack(int timeOut,msgQueueAck * ackMsg,Response* reply)
// {
//   int tmpTimeOut = timeOut;
//   int ret = 0;
//   if(tmpTimeOut==0)
//   {
//     tmpTimeOut = 1000;
//   }
//   else
//   {
//     tmpTimeOut*=1000;
//   }

//   int counter = tmpTimeOut/20;

//   while(counter>0)
//   {
//     ret = msgrcv( g_msg_id, ackMsg, sizeof(msgAck) ,QUEUE_MSG_TYPE_GRPC,IPC_NOWAIT );
//     if(ret>0)
//     {
//         printf("receive ack success!\n");
//         //if(moduleId == ackMsg->msg.moduleId)
//         //{
//           break;
//         //}        
//     }
//     usleep(20000);

//     counter--;
//   }

//   if(counter<=0)
//   {
//     reply->set_statecode(1);
//     reply->set_errornum(ACT_TIMEOUT);
//     ret = 1;
//   }
//   else
//   {  
//     if(ackMsg->msg.statusCode)
//     {
//       reply->set_errornum(ackMsg->msg.errorNum);
//       reply->set_statecode(1);
//       ret = 1;
//     }
//     else
//     {
//       reply->set_errornum(100);
//       reply->set_statecode(100);
//       ret = 0;
//     }
    
//   }

// }
